#define asm __asm__

extern void die(void);

extern void *memcpy(void *dst, const void *src, unsigned long size)
{
    void *pdst = dst, *psrc = (void *)src;
    asm volatile("rep movsb"
                 : "+D"(pdst), "+S"(psrc), "+c"(size)::"memory");
    return dst;
}

extern void *memcpy_reverse(void *dst, const void *src, unsigned long size)
{
    void *pdst = dst, *psrc = (void *)src;
    asm volatile("std; rep movsb; cld"
                 : "+D"(pdst), "+S"(psrc), "+c"(size)::"memory");
    return dst;
}

extern void *memset(void *ptr, int pad, unsigned long size)
{
    void *pptr = ptr;
    asm volatile("rep stosb"
                 : "+D"(pptr), "+c"(size)
                 : "a"((unsigned char)pad)
                 : "memory");
    return ptr;
}

extern int memcmp(const void *ptr1, const void *ptr2, unsigned long size)
{
    char *cp1, *cp2;
    cp1 = (char *)ptr1;
    cp2 = (char *)ptr2;
    while (size--)
    {
        if (*cp1 != *cp2)
            return *cp1 - *cp2;
        cp1++;
        cp2++;
    }
    return 0;
}

extern void *memmove(void *dst, const void *src, unsigned long size)
{
    if (src > dst)
    {
        return memcpy(dst, src, size);
    }
    else
    {
        return memcpy_reverse(dst, src, size);
    }
}

extern void _Unwind_Resume(void)
{
    die();
}
